package top.braycep.utils;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.io.File;
import java.io.FileFilter;
import java.util.Enumeration;
import java.util.Vector;

public class TreeUtils {
    public static void preview(JTree tree, String filename, DefaultTableModel tableModel) {
        if (StringUtils.isEmptyOrBlank(filename)) {
            filename = "Your Jar File";
        }

        DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
        DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) treeModel.getRoot();
        rootNode.setUserObject(filename.endsWith(".jar") ? filename : filename + ".jar");
        rootNode.removeAllChildren();

        Vector dataVector = tableModel.getDataVector();
        for (int i = 0; i < dataVector.size(); i++) {
            Vector row = (Vector) dataVector.get(i);
            String filepath = (String) row.get(1);
            String mappingPath = (String) row.get(3);
            String includeRegex = (String) row.get(4);
            String excludeRegex = (String) row.get(5);
            Boolean enable = (Boolean) row.get(6);
            enable = enable != null && enable;
            if (enable && StringUtils.isNotEmptyOrBlank(filepath)) {
                File file = new File(filepath);
                if (!file.exists()) {
                    continue;
                }
                if (file.isFile()) {
                    addNode(rootNode, file.getName(), mappingPath);
                } else {
                    addNode(rootNode, file, mappingPath, includeRegex, excludeRegex);
                }
            }
        }
    }

    public static void addNode(DefaultMutableTreeNode treeNode, File dir, String mappingPath, String includeRegexp, String excludeRegexp) {
        if (mappingPath == null) {
            mappingPath = "";
        }

        String[] ics = new String[]{};
        String[] ecs = new String[]{};
        if (StringUtils.isNotEmptyOrBlank(includeRegexp)) {
            ics = includeRegexp.split(";");
        }

        if (StringUtils.isNotEmptyOrBlank(excludeRegexp)) {
            ecs = excludeRegexp.split(";");
        }

        String[] finalIcs = ics;
        String[] finalEcs = ecs;
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File f) {
                if (f.isFile()) {
                    String filepath = f.getAbsolutePath();
                    for (String ic : finalIcs) {
                        if (!filepath.matches(ic)) {
                            return false;
                        }
                    }

                    for (String ec : finalEcs) {
                        if (filepath.matches(ec)) {
                            return false;
                        }
                    }
                }

                return true;
            }
        });

        for (File file : files) {
            if (file.isFile()) {
                addNode(treeNode, file.getName(), mappingPath);
            } else {
                if (StringUtils.isNotEmptyOrBlank(mappingPath)) {
                    mappingPath = mappingPath + "." + file.getName();
                } else {
                    mappingPath = file.getName();
                }
                addNode(treeNode, file, mappingPath, includeRegexp, excludeRegexp);
            }
        }
    }

    public static void addNode(DefaultMutableTreeNode treeNode, String filename, String mappingPath) {
        if (treeNode == null || StringUtils.isEmptyOrBlank(filename)) {
            return;
        }

        if (StringUtils.isEmptyOrBlank(mappingPath)) {
            mappingPath = "";
        }

        String prefix = "";
        if (mappingPath.contains(".")) {
            prefix = mappingPath.substring(0, mappingPath.indexOf("."));
        } else {
            prefix = mappingPath;
        }

        Enumeration children = treeNode.children();

        boolean existMappingNode = false;
        boolean existFileNode = false;
        DefaultMutableTreeNode mappingNode = null;
        while (children.hasMoreElements()) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) children.nextElement();
            String nodeName = (String) node.getUserObject();
            if (filename.equals(nodeName)) {
                existFileNode = true;
            }

            if (nodeName.equals(prefix)) {
                mappingNode = node;
                existMappingNode = true;
            }
        }

        if (StringUtils.isEmptyOrBlank(mappingPath)) {
            if (!existFileNode) {
                treeNode.add(new DefaultMutableTreeNode(filename));
            }
        } else {
            if (!existMappingNode) {
                mappingNode = new DefaultMutableTreeNode(prefix);
                treeNode.add(mappingNode);
            }

            String newMappingPath = "";
            if (mappingPath.contains(".")) {
                newMappingPath = mappingPath.substring(mappingPath.indexOf(".") + 1);
            }
            addNode(mappingNode, filename, newMappingPath);
        }
    }
}
